<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) 2023 https://inphp.cc All rights reserved.
// | Author: 幺月儿(https://gitee.com/lulanyin) Email: inphp@qq.com
// | 该文件的开源协议以所在项目的LICENSE文件为准，请遵守开源协议要求
// +----------------------------------------------------------------------
// | 微信接口
// +----------------------------------------------------------------------
namespace app\sso\http\api;

use app\sso\model\SceneModel;
use app\sso\model\ThirdPartyAppModel;
use app\sso\model\UserModel;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Request;
use Inphp\Core\Attributes\Method;
use Inphp\Core\Db\Db;
use Inphp\Core\Modules;
use Inphp\Core\Object\Message;
use Inphp\Core\Util\Str;

class wechat
{
    /**
     * 创建一个微信小程序码
     * @return Message
     */
    #[Method(Method::POST)] public function makeMPQRCode(): Message
    {
        //
        $scene = POST("scene");
        $scene = !empty($scene) ? trim($scene) : null;
        if (empty($scene)) {
            return httpMessage("缺少scene");
        }
        //
        $appid = POST("appid");
        $appid = !empty($appid) ? Str::trim($appid) : null;
        //
        $page = POST("page", "pages/index/index");
        //
        $hash = md5($scene);
        $exists = SceneModel::getHash($hash);
        if (empty($exists)) {
            if (!SceneModel::saveScene($scene)) {
                return httpMessage("保存scene失败");
            }
        }
        $client = new \app\sso\thirdParty\wechat\client($appid, "MP");
        if ($png = $client->getCodeUNLimit($hash, $page)) {
            //是否生成带验证码的
            $vc = POST("vc");
            $vc = $vc == 1;
            $vcName = POST("vcName");
            if ($vc) {
                $vcName = !empty($vcName) ? Str::trim($vcName) : null;
                $vCode = setTempVCode($vcName);
            }
            return httpMessage([
                "src"       => attachmentUrl($png),
                "vCode"     => $vCode ?? null
            ]);
        }
        return httpMessage("生成小程序码失败");
    }

    /**
     * 解码Scene
     * @return Message
     */
    public function scene(): Message
    {
        $hash = GET("hash");
        $hash = !empty($hash) && strlen($hash) == 32 ? $hash : null;
        if (empty($hash)) {
            return httpMessage("hash参数无效");
        }
        $scene = SceneModel::getHash($hash);
        if (!empty($scene)) {
            return httpMessage([
                "scene" => $scene
            ]);
        }
        return httpMessage("未找到数据");
    }

    /**
     * 使用 code 获取 openid
     * @return Message
     */
    public function openid(): Message
    {
        $code = POST("code");
        $code = !empty($code) ? $code : null;
        if (empty($code)) {
            return httpMessage("缺少 code");
        }
        $appid = HEADERS("APPID", POST("appid"));
        $appid = !empty($appid) ? $appid : null;

        //客户端类型，默认使用微信公众号
        $clientName = POST("clientName", "MP");
        $clientName = !empty($clientName) ? strtoupper($clientName) : "OA";
        $clientName = $clientName === "APP_BROWSER" ? "OA" : $clientName;
        $clientName = $clientName === "BROWSER" ? "WEB" : $clientName;
        if (!in_array($clientName, ["OA", "MP", "APP", "WEB"])) {
            return httpMessage("客户端类型无效");
        }

        //获取所有APPID列表
        $appidList = ThirdPartyAppModel::getList("wechat");
        if (empty($appidList)) {
            return httpMessage("没有可用的APPID");
        }
        //
        $secret = null;
        if (empty($appid)) {
            //从微信授权中，取一个合适的
            $appid = $appidList[0]["appid"] ?? null;
            $secret = $appidList[0]["secret"] ?? null;
            if (empty($appid)) {
                return httpMessage("未找到相应的APPID");
            }
        }
        if (empty($secret)) {
            foreach ($appidList as $app) {
                if ($app["appid"] === $appid) {
                    $secret = $app["secret"];
                }
            }
            if (empty($secret)) {
                return httpMessage("未找到相应APPID配置");
            }
        }

        //微信接口服务端地址
        $url = match ($clientName) {
            //公众号、网页、APP
            "OA", "WEB", "APP" => "https://api.weixin.qq.com/sns/oauth2/access_token",
            //小程序
            "MP"    => "https://api.weixin.qq.com/sns/jscode2session"
        };
        //参数
        $params = [
            "appid"     => $appid,
            "secret"    => $secret,
            //小程序的是JS_CODE
            ($clientName === "MP" ? "js_code" : "code") => $code,
            //
            "grant_type"    => "authorization_code"
        ];
        $url .= "?".makeUrlQuery($params, false);
        try {
            //获取结果
            $httpClient = new Client();
            $request = new Request("GET", $url);
            $response = $httpClient->send($request, ["timeout" => 3]);
            if ($response->getStatusCode() === 200) {
                $content = $response->getBody()->getContents();
                $json = !empty($content) ? (@json_decode($content, true) ?? null) : null;
                if (is_array($json) && isset($json["openid"])) {
                    return httpMessage($json);
                }
                return httpMessage("未取得OPENID结果数据".(isset($json["errcode"]) ? ("，错误码：{$json["errcode"]}/{$json["errmsg"]}") : ""));
            } else {
                return httpMessage("请求微信接口失败，HTTP状态码：{$response->getStatusCode()}");
            }
        } catch (GuzzleException $exception) {
            return httpMessage(1, $exception->getMessage());
        }
    }

    public function kf(): Message
    {
        $uid = GET("uid");
        $uid = is_numeric($uid) && $uid > 0 ? $uid : 0;
        $username = GET("username");
        $username = !empty($username) ? Str::trim($username) : null;
        //
        $nickname = '';
        //默认客服
        $qwkf = Modules::getModule("sso")->getConfig("qwkf");
        $qwkf = is_array($qwkf) ? $qwkf : ["appid" => "", "url" => ""];
        if ($uid === 0 && empty($username)) {
            //取默认客服
            return httpMessage($qwkf);
        }
        if ($uid === 0) {
            $user = UserModel::emptyQuery()->where("username", $username)->first();
            if (empty($user)) {
                return httpMessage($qwkf);
            }
        } else {
            $user = UserModel::emptyQuery()->where("uid", $uid)->first();
            if (empty($user)) {
                return httpMessage($qwkf);
            }
        }
        $uid = $user["uid"];
        $nickname = !empty($user["nickname"]) ? UserModel::decodeNickname($user["nickname"]) : (!empty($user["phone"]) ? $user["phone"] : $user["username"]);
        $face = !empty($user["face"]) ? attachmentUrl($user["face"]) : null;
        $kf = Db::from("sso_userQWKF")->where("uid", $uid)->first();
        $kf["appid"] = $kf["appid"] == "null" ? $qwkf["appid"] : $kf["appid"];
        if (!empty($kf) && !empty($kf["appid"]) && !empty($kf["url"])) {
            $kf["nickname"] = $nickname;
            $kf["face"] = $face;
            return httpMessage($kf);
        }
        return httpMessage($qwkf);
    }
}